package lapsnake.ui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import lapsnake.model.expr.LapName;

public class JIdentifierField extends JTextField implements DocumentListener, FocusListener
{
	private static final long serialVersionUID = -4891568719799068070L;

	private boolean hack = false;

	private String value;

	private Color origColor;
	
	public JIdentifierField(String value)
	{
		super(value);

		setFont(Fonts.smallUI.deriveFont(Font.BOLD));
		setForeground(new Color(0x004297));
		
		updateSize();
		
		origColor = getBackground();
		this.value = value;
		
		getDocument().addDocumentListener(this);
		addFocusListener(this);
	}

	private void updateSize()
	{
		setPreferredSize(null);
		Dimension preferredSize = getPreferredSize();
		preferredSize.width += 6;
		preferredSize.height -= 2;
		setPreferredSize(preferredSize);
		if(getParent() != null)
			getParent().revalidate();
	}

	@Override
	public void changedUpdate(DocumentEvent arg0)
	{
		documentChanged();
	}

	@Override
	public void insertUpdate(DocumentEvent arg0)
	{
		documentChanged();
	}

	@Override
	public void removeUpdate(DocumentEvent arg0)
	{
		documentChanged();
	}

	private void documentChanged()
	{
		try 
		{
			if(!hack)
			{
				hack = true;
				LapName.validate(getText());
				setBackground(origColor);
			}
		}
		catch(IllegalArgumentException e)
		{
			setBackground(Color.RED);
		}
		finally
		{
			updateSize();
			hack = false;
		}
	}

	@Override
	protected void fireActionPerformed()
	{
		//This is stupid but it should work.
		if(hack)
			super.fireActionPerformed();
		else
			update();
	}

	@Override
	public void focusGained(FocusEvent e)
	{
		
	}

	@Override
	public void focusLost(FocusEvent e)
	{
		update();
	}

	private void update()
	{
		try 
		{
			if(!hack)
			{
				hack = true;
				if(!getText().equals(value))
				{
					LapName.validate(getText());
					value = getText();
					setBackground(origColor);
					fireActionPerformed();
				}
			}
		}
		catch(IllegalArgumentException e)
		{
			setText(value);
			updateSize();
			setBackground(origColor);
		}
		finally
		{
			hack = false;
		}
	}
}
